package org.Yiran.timetale_re.item.rune.base;

import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.network.chat.TextColor;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.Yiran.timetale_re.block.decorate.longtable.LongTable;
import org.Yiran.timetale_re.item.ItemsRegister;
import org.Yiran.timetale_re.item.runeblueprint.base.RuneBlueprintItem;
import org.Yiran.timetale_re.tile.blocktile.LongTableBlockEntity;
import org.Yiran.timetale_re.util.cooldown.CooldownManager;
import org.Yiran.timetale_re.util.item.TooltipUtils;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nullable;
import java.util.List;
import java.util.Objects;

/**
 * 符文物品类
 * <p>
 * 该类表示游戏中的符文物品，通过NBT数据区分不同类型的符文。
 * 提供了符文类型管理、雕刻系统、冷却系统等功能。
 * </p>
 */
public class RuneItem extends Item {
    
    // ============================== 符文类型常量 ==============================
    
    public static final String RUNE_TYPE = "RuneType";
    public static final String BLANK = "blank";
    public static final String STORM = "storm";
    public static final String THUNDER = "thunder";
    public static final String LIFE = "life";
    
    // ============================== 符文分类常量 ==============================
    
    public static final String CATEGORY = "RuneCategory";
    public static final String THROWABLE = "throwable"; // 投掷类
    public static final String FUNCTIONAL = "functional"; // 功能类
    public static final String AMPLIFICATION = "amplification"; // 增幅类
    public static final String NONE = "none"; // 空
    
    // ============================== 雕刻相关常量 ==============================
    
    public static final String CARVING_TARGET = "CarvingTarget"; // 将要雕刻的符文类型
    public static final String CARVING_PROGRESS = "CarvingProgress"; // 雕刻进度
    
    // ============================== 符文等级常量 ==============================
    
    public static final String RUNE_LEVEL = "RuneLevel";

    // ============================== 构造方法 ==============================
    
    /**
     * 构造函数
     * 
     * @param properties 物品属性
     */
    public RuneItem(Properties properties) {
        super(properties);
    }

    // ============================== 模型相关方法 ==============================
    
    /**
     * 获取符文的模型资源位置
     * 
     * @param stack 符文物品栈
     * @param level 世界对象
     * @param entity 生物实体
     * @param seed 随机种子
     * @return 模型资源位置
     */
    @OnlyIn(Dist.CLIENT)
    public ResourceLocation getModel(ItemStack stack, @Nullable Level level, @Nullable LivingEntity entity, int seed) {
        String runeType = getRuneType(stack);
        return ResourceLocation.fromNamespaceAndPath("timetale_re", "item/" + runeType + "_rune");
    }

    // ============================== 符文等级相关方法 ==============================
    
    /**
     * 获取符文等级
     * 
     * @param stack 符文物品栈
     * @return 符文等级，如果未设置则返回默认值1
     */
    public static int getRuneLevel(ItemStack stack) {
        CompoundTag tag = stack.getTag();
        if (tag != null && tag.contains(RUNE_LEVEL)) {
            return tag.getInt(RUNE_LEVEL);
        }
        return 1; // 默认等级为1
    }

    /**
     * 设置符文等级
     * 
     * @param stack 符文物品栈
     * @param level 等级值
     */
    public static void setRuneLevel(ItemStack stack, int level) {
        CompoundTag tag = stack.getOrCreateTag();
        tag.putInt(RUNE_LEVEL, level);
    }

    // ============================== 雕刻验证方法 ==============================
    
    /**
     * 验证当前雕刻目标是否与桌面上的图纸匹配
     * 
     * @param stack 符文物品堆
     * @param tableEntity 长桌实体
     * @param partId 当前部分ID
     * @return 如果匹配返回true，否则返回false
     */
    public static boolean validateCarvingTarget(ItemStack stack, LongTableBlockEntity tableEntity, int partId) {
        if (!isBeingCarved(stack)) {
            return false;
        }

        String targetType = getCarvingTarget(stack);
        if (targetType == null) {
            return false;
        }

        // 查找相邻部分的图纸
        int otherPartId = (partId == LongTable.LEFT_PART) ? LongTable.RIGHT_PART : LongTable.LEFT_PART;
        ItemStack otherItem = tableEntity.getItem(otherPartId);

        // 检查图纸是否存在且类型匹配
        if (otherItem.getItem() instanceof RuneBlueprintItem) {
            String blueprintType = RuneBlueprintItem.getRuneType(otherItem);
            return targetType.equals(blueprintType);
        }

        return false;
    }

    // ============================== 雕刻目标相关方法 ==============================
    
    /**
     * 设置符文的雕刻目标
     * 
     * @param stack 符文物品堆
     * @param targetType 目标符文类型
     */
    public static void setCarvingTarget(ItemStack stack, String targetType) {
        CompoundTag tag = stack.getOrCreateTag();
        // 只有空白符文可以设置雕刻目标
        if (isBlankRune(stack)) {
            tag.putString(CARVING_TARGET, targetType);
        }
    }

    /**
     * 获取符文的雕刻目标
     * 
     * @param stack 符文物品堆
     * @return 目标符文类型，如果没有则返回null
     */
    public static String getCarvingTarget(ItemStack stack) {
        CompoundTag tag = stack.getTag();
        if (tag != null && tag.contains(CARVING_TARGET)) {
            return tag.getString(CARVING_TARGET);
        }
        return null;
    }

    // ============================== 雕刻进度相关方法 ==============================
    
    /**
     * 设置符文的雕刻进度
     * 
     * @param stack 符文物品堆
     * @param progress 雕刻进度 (0-100)
     */
    public static void setCarvingProgress(ItemStack stack, double progress) {
        CompoundTag tag = stack.getOrCreateTag();
        // 只有空白符文可以设置雕刻进度
        if (isBlankRune(stack)) {
            tag.putDouble(CARVING_PROGRESS, Math.max(0.0, Math.min(100.0, progress)));
        }
    }

    /**
     * 获取符文的雕刻进度
     * 
     * @param stack 符文物品堆
     * @return 雕刻进度 (0-100)，如果没有则返回0
     */
    public static double getCarvingProgressDouble(ItemStack stack) {
        CompoundTag tag = stack.getTag();
        if (tag != null && tag.contains(CARVING_PROGRESS)) {
            return tag.getDouble(CARVING_PROGRESS);
        }
        return 0.0;
    }

    /**
     * 获取符文的雕刻进度（整数形式，向下取整）
     * 
     * @param stack 符文物品堆
     * @return 雕刻进度 (0-100)，如果没有则返回0
     */
    public static int getCarvingProgress(ItemStack stack) {
        return (int) getCarvingProgressDouble(stack);
    }

    /**
     * 增加符文的雕刻进度
     * 
     * @param stack 符文物品堆
     * @param increment 增量
     * @return 当前进度
     */
    public static double incrementCarvingProgress(ItemStack stack, double increment) {
        double currentProgress = getCarvingProgressDouble(stack);
        double newProgress = Math.min(100.0, currentProgress + increment);
        setCarvingProgress(stack, newProgress);
        return newProgress;
    }

    /**
     * 检查符文是否正在被雕刻
     * 
     * @param stack 符文物品堆
     * @return 如果正在雕刻返回true
     */
    public static boolean isBeingCarved(ItemStack stack) {
        return isBlankRune(stack) && getCarvingTarget(stack) != null;
    }

    /**
     * 完成雕刻过程，将空白符文转换为目标符文
     * 
     * @param stack 空白符文物品堆
     * @return 转换后的符文物品堆
     */
    public static ItemStack finishCarving(ItemStack stack) {
        if (isBeingCarved(stack) && getCarvingProgress(stack) >= 100) {
            String targetRuneType = getCarvingTarget(stack);
            if (targetRuneType != null) {
                ItemStack newRune = new ItemStack(getRuneItem());

                // 复制其他可能的标签（除了雕刻相关标签）
                copyTagsExcludingCarvingData(stack, newRune);

                // 最后设置符文类型，确保不会被覆盖
                setRuneType(newRune, targetRuneType);

                System.out.println("完成雕刻，从空白符文转换为: " + targetRuneType + " 符文");
                System.out.println("新符文类型: " + getRuneType(newRune));
                return newRune;
            }
        }
        return stack;
    }

    /**
     * 复制标签数据（排除雕刻相关标签）
     * 
     * @param source 源物品堆
     * @param target 目标物品堆
     */
    private static void copyTagsExcludingCarvingData(ItemStack source, ItemStack target) {
        if (source.hasTag()) {
            CompoundTag originalTag = source.getTag();
            CompoundTag newTag = target.getOrCreateTag();

            // 复制除雕刻相关以外的标签
            if (originalTag != null) {
                for (String key : originalTag.getAllKeys()) {
                    // 不复制雕刻相关的标签
                    if (!CARVING_TARGET.equals(key) && !CARVING_PROGRESS.equals(key)) {
                        newTag.put(key, Objects.requireNonNull(originalTag.get(key)).copy());
                    }
                }
            }
        }
    }

    // ============================== 符文物品实例方法 ==============================
    
    /**
     * 获取符文物品实例
     * 
     * @return 符文物品
     */
    public static Item getRuneItem() {
        return ItemsRegister.RUNE.get();
    }

    // ============================== 符文类型相关方法 ==============================
    
    /**
     * 设置符文类型
     * 
     * @param stack 符文物品栈
     * @param type 符文类型
     */
    public static void setRuneType(ItemStack stack, String type) {
        CompoundTag tag = stack.getOrCreateTag();
        tag.putString(RUNE_TYPE, type);

        // 设置符文分类
        setRuneCategory(tag, type);

        tag.putFloat("timetale_re:rune_type", getTypePredicateValue(type));

        // 清除非空白符文的雕刻信息
        if (!BLANK.equals(type)) {
            tag.remove(CARVING_TARGET);
            tag.remove(CARVING_PROGRESS);
        }
    }

    /**
     * 设置符文分类信息
     * 
     * @param tag NBT标签
     * @param type 符文类型
     */
    private static void setRuneCategory(CompoundTag tag, String type) {
        // 从注册表获取分类信息
        RuneAbility ability = RuneRegistry.getRuneAbility(type);
        if (ability != null) {
            tag.putString(CATEGORY, ability.getCategory());
        } else {
            tag.putString(CATEGORY, getRuneCategory(type));
        }
    }

    /**
     * 获取符文类型对应的谓词值
     * 
     * @param type 符文类型
     * @return 对应的谓词值
     */
    public static int getTypePredicateValue(String type) {
        return switch (type) {
            case STORM -> 1;
            case THUNDER -> 2;
            case LIFE -> 3;
            default -> 0;
        };
    }

    /**
     * 获取符文类型
     * 
     * @param stack 符文物品栈
     * @return 符文类型，如果未设置则返回默认值BLANK
     */
    public static String getRuneType(ItemStack stack) {
        CompoundTag tag = stack.getTag();
        if (tag != null && tag.contains(RUNE_TYPE)) {
            return tag.getString(RUNE_TYPE);
        }
        return BLANK; // 默认为空白符文
    }

    // ============================== 符文分类相关方法 ==============================
    
    /**
     * 根据符文类型获取其分类
     * 
     * @param runeType 符文类型
     * @return 符文分类
     */
    public static String getRuneCategory(String runeType) {
        RuneAbility ability = RuneRegistry.getRuneAbility(runeType);
        if (ability != null) {
            return ability.getCategory();
        }

        return switch (runeType) {
            case STORM -> FUNCTIONAL; // 风暴符文是功能类
            case BLANK -> NONE; // 空白符文不属于任何类别
            case LIFE -> AMPLIFICATION; // 生命符文是增幅类
            default -> NONE; // 默认无类别
        };
    }

    /**
     * 获取符文分类
     * 
     * @param stack 符文物品栈
     * @return 符文分类，如果未设置则返回默认值NONE
     */
    public static String getRuneCategory(ItemStack stack) {
        CompoundTag tag = stack.getTag();
        if (tag != null && tag.contains(CATEGORY)) {
            return tag.getString(CATEGORY);
        }
        return NONE; // 默认无类别
    }

    // ============================== 创建符文方法 ==============================
    
    /**
     * 创建空白符文
     * 
     * @return 空白符文物品栈
     */
    public static ItemStack createBlankRune() {
        ItemStack stack = new ItemStack(getRuneItem());
        setRuneType(stack, BLANK);
        return stack;
    }

    /**
     * 创建风暴符文
     * 
     * @return 风暴符文物品栈
     */
    public static ItemStack createStormRune() {
        ItemStack stack = new ItemStack(getRuneItem());
        setRuneType(stack, STORM);
        return stack;
    }

    /**
     * 创建雷暴符文
     * 
     * @return 雷暴符文物品栈
     */
    public static ItemStack createThunderRune() {
        ItemStack stack = new ItemStack(getRuneItem());
        setRuneType(stack, THUNDER);
        return stack;
    }

    /**
     * 创建生命符文
     * 
     * @return 生命符文物品栈
     */
    public static ItemStack createLifeRune() {
        ItemStack stack = new ItemStack(getRuneItem());
        setRuneType(stack, LIFE);
        return stack;
    }
    
    // ============================== 符文类型检查方法 ==============================
    
    /**
     * 检查是否为空白符文
     * 
     * @param stack 符文物品栈
     * @return 如果是空白符文返回true
     */
    public static boolean isBlankRune(ItemStack stack) {
        return BLANK.equals(getRuneType(stack));
    }

    /**
     * 检查是否为风暴符文
     * 
     * @param stack 符文物品栈
     * @return 如果是风暴符文返回true
     */
    public static boolean isStormRune(ItemStack stack) {
        return STORM.equals(getRuneType(stack));
    }

    /**
     * 检查是否为投掷类符文
     * 
     * @param stack 符文物品栈
     * @return 如果是投掷类符文返回true
     */
    public static boolean isThrowableRune(ItemStack stack) {
        return THROWABLE.equals(getRuneCategory(stack));
    }

    /**
     * 检查是否为功能类符文
     * 
     * @param stack 符文物品栈
     * @return 如果是功能类符文返回true
     */
    public static boolean isFunctionalRune(ItemStack stack) {
        return FUNCTIONAL.equals(getRuneCategory(stack));
    }

    /**
     * 检查是否为增幅类符文
     * 
     * @param stack 符文物品栈
     * @return 如果是增幅类符文返回true
     */
    public static boolean isAmplificationRune(ItemStack stack) {
        return AMPLIFICATION.equals(getRuneCategory(stack));
    }

    // ============================== 物品交互方法 ==============================
    
    /**
     * 使用物品时的处理方法
     * <p>
     * 处理符文的冷却和使用逻辑
     * </p>
     * 
     * @param level 世界对象
     * @param player 玩家对象
     * @param hand 使用的手
     * @return 交互结果
     */
    @Override
    public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level level, Player player, @NotNull InteractionHand hand) {
        ItemStack stack = player.getItemInHand(hand);
        String runeType = getRuneType(stack);
        String runeCategory = getRuneCategory(stack);

        // 检查冷却时间
        if (!canUseRune(player, runeCategory, stack)) {
            return InteractionResultHolder.fail(stack);
        }

        RuneAbility ability = RuneRegistry.getRuneAbility(runeType);

        // 只有已注册的符文可以被使用
        if (ability != null) {
            handleRuneCooldown(level, player, stack, runeCategory, ability);
            
            // 调用符文管理器处理符文使用
            RuneManager.useRune(stack, level, player);

            // 检查是否为已雕刻的符文，如果是则使用后直接损耗掉
            if (isCarvedRune(stack)) {
                stack.shrink(1);
                return InteractionResultHolder.success(stack);
            }
        }

        return InteractionResultHolder.success(stack);
    }

    /**
     * 检查符文是否可以使用（冷却检查）
     * 
     * @param player 玩家
     * @param runeCategory 符文分类
     * @param stack 符文物品堆
     * @return 如果可以使用返回true
     */
    private boolean canUseRune(Player player, String runeCategory, ItemStack stack) {
        // 投掷类符文不受冷却限制
        return THROWABLE.equals(runeCategory) || CooldownManager.isCooldownOverWithSound(player, "rune", stack);
    }

    /**
     * 处理符文冷却逻辑
     * 
     * @param level 世界对象
     * @param player 玩家
     * @param stack 符文物品堆
     * @param runeCategory 符文分类
     * @param ability 符文能力
     */
    private void handleRuneCooldown(Level level, Player player, ItemStack stack, String runeCategory, RuneAbility ability) {
        // 在服务端设置冷却（投掷类符文不设置冷却）
        if (!level.isClientSide && !THROWABLE.equals(runeCategory)) {
            // 使用符文子类中定义的冷却时间
            int cooldownTicks = ability.getCooldown();
            CooldownManager.setCooldown(player, "rune", stack, cooldownTicks);
        }
    }

    /**
     * 检查符文是否为已雕刻的符文（非空白符文）
     * 
     * @param stack 符文物品堆
     * @return 如果是已雕刻的符文返回true
     */
    private boolean isCarvedRune(ItemStack stack) {
        // 空白符文不是雕刻符文，其他都是
        return !isBlankRune(stack);
    }

    // ============================== 客户端显示方法 ==============================
    
    /**
     * 添加物品悬停文本提示
     * 
     * @param stack 物品栈
     * @param level 世界对象
     * @param tooltip 提示文本列表
     * @param flag 提示标志
     */
    @Override
    @OnlyIn(Dist.CLIENT)
    public void appendHoverText(@NotNull ItemStack stack, @Nullable Level level, @NotNull List<Component> tooltip, @NotNull TooltipFlag flag) {
        super.appendHoverText(stack, level, tooltip, flag);

        String runeType = getRuneType(stack);
        String runeCategory = getRuneCategory(stack);
        int runeLevel = getRuneLevel(stack);
        boolean isBlank = isBlankRune(stack);
        
        // 添加基础描述
        TooltipUtils.addRuneBaseDescription(tooltip, runeType);
        
        // 显示符文种类和等级
        TooltipUtils.addRuneTypeInfo(tooltip, runeCategory, runeLevel, isBlank);
        
        // 显示雕刻信息
        addCarvingInfo(tooltip, stack, isBlank);
        
        // 显示冷却时间信息
        addCooldownInfo(tooltip, runeType);
        
        // 添加分割线
        TooltipUtils.addSeparatorLine(tooltip);
        
        // 添加详细信息或提示
        addDetailedOrPromptInfo(tooltip, runeType);
    }

    /**
     * 添加雕刻信息
     * 
     * @param tooltip 提示列表
     * @param stack 符文物品堆
     * @param isBlank 是否为空白符文
     */
    @OnlyIn(Dist.CLIENT)
    private void addCarvingInfo(List<Component> tooltip, ItemStack stack, boolean isBlank) {
        // 只有当空白符文同时具有雕刻目标和进度时才显示相关信息
        if (stack.getTag() != null && isBlank && getCarvingTarget(stack) != null && stack.hasTag() && stack.getTag().contains(CARVING_PROGRESS)) {
            String targetType = getCarvingTarget(stack);
            double progress = getCarvingProgressDouble(stack);
            // 显示雕刻信息
            TooltipUtils.addRuneCarvingInfo(tooltip, targetType, progress);
        }
    }

    /**
     * 添加冷却时间信息
     * 
     * @param tooltip 提示列表
     * @param runeType 符文类型
     */
    @OnlyIn(Dist.CLIENT)
    private void addCooldownInfo(List<Component> tooltip, String runeType) {
        RuneAbility ability = RuneRegistry.getRuneAbility(runeType);
        if (ability != null) {
            int cooldown = ability.getCooldown();
            if (cooldown > 0) {
                double cooldownSeconds = cooldown / 20.0;
                TooltipUtils.addRuneCooldownInfo(tooltip, cooldownSeconds);
            }
        }
    }

    /**
     * 添加详细信息或提示
     * 
     * @param tooltip 提示列表
     * @param runeType 符文类型
     */
    @OnlyIn(Dist.CLIENT)
    private void addDetailedOrPromptInfo(List<Component> tooltip, String runeType) {
        String detailKey = "item.timetale_re." + runeType + "_rune.detail";
        boolean isShiftPressed = Screen.hasShiftDown();

        if (isShiftPressed) {
            // 显示详细信息
            if (I18n.exists(detailKey)) {
                tooltip.add(Component.translatable(detailKey)
                        .setStyle(Style.EMPTY.withColor(TextColor.parseColor("#AAAAAA"))));
            }
        } else {
            // 提示按Shift查看详细信息
            TooltipUtils.addShiftPrompt(tooltip);
        }
    }

    /**
     * 获取物品显示名称
     * 
     * @param stack 物品栈
     * @return 物品名称组件
     */
    @Override
    public @NotNull Component getName(@NotNull ItemStack stack) {
        String runeType = getRuneType(stack);
        return Component.translatable("item.timetale_re." + runeType + "_rune");
    }
}